#include <iostream>
#include "proxy.h"

struct Crow{};
void fly(const Crow&) {
    std::cout << "crow fly";
}

struct Duck{};
void fly(const Duck&) {
    std::cout << "duck ";
}

PRO_DEF_FREE_DISPATCH(FnFly, fly, Fly);

struct Flyable: pro::facade_builder
    ::add_convention<FnFly, void()>
    ::support_copy<pro::constraint_level::nontrivial>
    ::build
    {};

void dynamic_fly(pro::proxy<Flyable> flyable)
{
    Fly(*flyable);
}

int main(void) {
    int choice = 0;
    std::cin >> choice;
    pro::proxy<Flyable> flyable;
    if (choice == 0) {
        flyable = pro::make_proxy<Flyable>(Crow{});
    } else {
        flyable = pro::make_proxy<Flyable>(Duck{});
    }
    dynamic_fly(flyable);
    return 0;
}
